/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.zyyoona7.picker;

import com.zyyoona7.picker.listener.PickerValueChange;
import com.zyyoona7.picker.util.LogUtils;

import ohos.agp.components.Component;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.Picker;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.AttrSet;
import ohos.agp.components.LayoutScatter;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.app.Context;
import ohos.agp.utils.Color;
import ohos.global.resource.RawFileDescriptor;
import ohos.media.common.Source;
import ohos.media.player.Player;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 描述 城市选择器
 *
 * @author wjt
 * @since 2021-04-12
 */
public class CityPicker extends DirectionalLayout implements Picker.ValueChangedListener, Component.DrawTask {
    /**
     * 数据改变接口实例
     */
    private PickerValueChange pickerValueChange;
    private Context context;
    /**
     * 0.15
     */
    private static final double lyw = 0.15;
    /**
     * 字体大小
     */
    private static final int mTextSize = 40;
    private static final int fifty = 50;
    private static final int thirty = 8;
    private static final int seven = 7;
    private static final int eight = 8;

    /**
     * 5
     */
    private static final int five = 5;
    /**
     * 0
     */
    private static final int zero = 0;
    /**
     * 2
     */
    private static final int two = 2;
    /**
     * 3
     */
    private static final int three = 3;
    /**
     * 3
     */
    private static final int twoty = 20;

    /**
     * 选中的背景
     */
    private boolean isSelectedtextbackground = false;
    /**
     * 是否显示阴影
     */
    private boolean isShowshadow = false;
    /**
     * 是否播放声音
     */
    private boolean isSound = false;
    /**
     * 音频
     */
    private SoundHelper mSoundHelper;
    private List<CityEntity> p3List = new ArrayList<>(1);
    private List<List<CityEntity>> c3List = new ArrayList<>(1);
    private List<List<List<CityEntity>>> d3List = new ArrayList<>(1);
    private Picker province;
    private Picker city;
    private Picker county;
    private String provinceValue = "";
    private String cityValue = "";
    private String countyValue = "";
    private List<CityEntity> provinceEntityList = new ArrayList<>();
    private List<CityEntity> cityEntityList = new ArrayList<>();
    private List<CityEntity> countyEntityList = new ArrayList<>();
    private int yijixiabiao = 0;
    private int erjixiabiao = 0;
    private Picker.Formatter provinceFormatter;
    private Picker.Formatter cityFormatter;
    private Picker.Formatter countyFormatter;

    /**
     * 构造
     *
     * @param context
     */
    public CityPicker(Context context) {
        super(context);
        this.context = context;
        initView(context);
    }

    /**
     * 构造
     *
     * @param context
     * @param attrSet
     */
    public CityPicker(Context context, AttrSet attrSet) {
        super(context, attrSet);
        this.context = context;
        initTypeValue(context, attrSet);
        initView(context);
    }

    /**
     * 初始化
     *
     * @param context1
     */
    private void initView(Context context1) {
        Component component1 = LayoutScatter.getInstance(context1)
                .parse(ResourceTable.Layout_layout_picker_city, this, false);
        initLayout(component1);
        setOrientation(VERTICAL);
        addComponent(component1);
    }

    /**
     * 初始化
     *
     * @param component1
     */
    private void initLayout(Component component1) {
        province = (Picker) component1.findComponentById(ResourceTable.Id_province);
        province.setValueChangedListener(this::onValueChanged);
        attributesSet();
        city = (Picker) component1.findComponentById(ResourceTable.Id_city);
        city.setValueChangedListener(this::onValueChanged);
        county = (Picker) component1.findComponentById(ResourceTable.Id_county);
        county.setValueChangedListener(this::onValueChanged);
        synchronizedList();
        provinceValue = p3List.get(0).getName();
        cityValue = c3List.get(0).get(0).getName();
        countyValue = d3List.get(0).get(0).get(0).getName();
        provinceEntityList.clear();
        provinceEntityList.addAll(p3List);
        province.setValue(0);
        province.setMinValue(0);
        province.setMaxValue(provinceEntityList.size() - 1);
        provinceFormatter = new Picker.Formatter() {
            @Override
            public String format(int i) {
                return provinceEntityList.get(i).getName();
            }
        };
        province.setFormatter(provinceFormatter);
        cityEntityList.clear();
        cityEntityList.addAll(c3List.get(yijixiabiao));
        city.setValue(0);
        city.setMinValue(0);
        city.setMaxValue(cityEntityList.size() - 1);
        cityFormatter = new Picker.Formatter() {
            @Override
            public String format(int i) {
                return cityEntityList.get(i).getName();
            }
        };
        city.setFormatter(cityFormatter);
        countyEntityList.clear();
        countyEntityList.addAll(d3List.get(yijixiabiao).get(erjixiabiao));
        county.setValue(0);
        county.setMinValue(0);
        county.setMaxValue(countyEntityList.size() - 1);

        countyFormatter = new Picker.Formatter() {
            @Override
            public String format(int i) {
                return countyEntityList.get(i).getName();
            }
        };
        county.setFormatter(countyFormatter);
    }

    private void synchronizedList() {
        ParseHelper.initThreeLevelCityList(context, p3List, c3List, d3List);
        p3List = Collections.synchronizedList(p3List);
        c3List = Collections.synchronizedList(c3List);
        d3List = Collections.synchronizedList(d3List);
    }

    private void attributesSet() {
        if (isSelectedtextbackground) {
            ShapeElement shapeElement = new ShapeElement(context, ResourceTable.Graphic_background_ability_test);
            shapeElement.setShape(ShapeElement.LINEAR_GRADIENT_SHADER_TYPE);
            province.setDisplayedLinesBottomElement(shapeElement);
            province.setDisplayedLinesTopElement(shapeElement);
            province.setSelectedTextBackground(shapeElement);
        }
        if (isShowshadow) {
            addDrawTask(this::onDraw);
        }
        if (isSound) {
            setSoundEffectResource("resources/rawfile/button_choose.ogg");
        }
    }

    /**
     * 初始化自定义属性
     *
     * @param mcontext 上下文
     * @param attrSet 自定义属性
     */
    private void initTypeValue(Context mcontext, AttrSet attrSet) {
        isSelectedtextbackground = getAttrSetBoolean(attrSet, "select_background", false);
        isShowshadow = getAttrSetBoolean(attrSet, "isshow_shadow", false);
        isSound = getAttrSetBoolean(attrSet, "issound", false);
    }

    private int getAttrSetInt(AttrSet attrs, String key, int def) {
        if (attrs.getAttr(key).isPresent()) {
            return attrs.getAttr(key).get().getIntegerValue();
        } else {
            return def;
        }
    }

    private float getAttrSetFloat(AttrSet attrs, String key, float def) {
        if (attrs.getAttr(key).isPresent()) {
            return attrs.getAttr(key).get().getFloatValue();
        } else {
            return def;
        }
    }

    private boolean getAttrSetBoolean(AttrSet attrs, String key, boolean isDef) {
        if (attrs.getAttr(key).isPresent()) {
            return attrs.getAttr(key).get().getBoolValue();
        } else {
            return isDef;
        }
    }

    private Color getAttrSetColor(AttrSet attrs, String key, Color color) {
        if (attrs.getAttr(key).isPresent()) {
            return attrs.getAttr(key).get().getColorValue();
        } else {
            return color;
        }
    }

    private String getAttrSetString(AttrSet attrs, String key, String str) {
        if (attrs.getAttr(key).isPresent()) {
            return attrs.getAttr(key).get().getStringValue();
        } else {
            return str;
        }
    }

    /**
     * picker值更改事件
     *
     * @param picker picker
     * @param positon 现在的下标
     * @param i1 即将选择的下标
     */
    @Override
    public void onValueChanged(Picker picker, int positon, int i1) {
        playSoundEffect();
        if (picker.getId() == ResourceTable.Id_province) {
            provinceValue = provinceEntityList.get(i1).getName();
            if (provinceValue.length() > seven) {
                picker.setSelectedTextSize(mTextSize);
            } else {
                picker.setSelectedTextSize(fifty);
            }
            cityEntityList.clear();
            cityEntityList.addAll(c3List.get(i1));
            cityValue = cityEntityList.get(0).getName();
            yijixiabiao = i1;
            city.setMinValue(0);
            city.setMaxValue(cityEntityList.size() - 1);
            city.setFormatter(null);
            city.setFormatter(cityFormatter);
            city.setValue(0);
            erjixiabiao = 0;
            countyEntityList.clear();
            countyEntityList.addAll(d3List.get(yijixiabiao).get(erjixiabiao));
            countyValue = countyEntityList.get(0).getName();

            settingPicker(countyEntityList,county);

            if (pickerValueChange != null) {
                pickerValueChange.valueChange(provinceValue, cityValue, countyValue);
            }
        } else if (picker.getId() == ResourceTable.Id_city) {
            erjixiabiao = i1;
            countyEntityList.clear();
            countyEntityList.addAll(d3List.get(yijixiabiao).get(erjixiabiao));
            cityValue = cityEntityList.get(i1).getName();
            if (cityValue.length() > eight) {
                picker.setSelectedTextSize(thirty);
            } else {
                picker.setSelectedTextSize(fifty);
            }

            settingPicker(countyEntityList,county);
            if (pickerValueChange != null) {
                pickerValueChange.valueChange(provinceValue, cityValue, countyValue);
            }
        } else if (picker.getId() == ResourceTable.Id_county) {
            countyValue = countyEntityList.get(i1).getName();
            if (countyValue.length() > eight) {
                picker.setSelectedTextSize(thirty);
            }
            if (pickerValueChange != null) {
                pickerValueChange.valueChange(provinceValue, cityValue, countyValue);
            }
        }
    }

    private void settingPicker(List<CityEntity> countyEntityList1, Picker picker) {
        picker.setMinValue(0);
        picker.setMaxValue(countyEntityList1.size() - 1);
        picker.setFormatter(null);
        picker.setFormatter(countyFormatter);
        picker.setValue(0);
    }

    /**
     * setValuChange
     *
     * @param valueChange
     */
    public void setValuChange(PickerValueChange valueChange) {
        this.pickerValueChange = valueChange;
    }

    /**
     * getProvinceValue
     *
     * @return ProvinceValue
     */
    public String getProvinceValue() {
        return provinceValue;
    }

    /**
     * setProvinceValue
     *
     * @param provinceValue
     */
    public void setProvinceValue(String provinceValue) {
        this.provinceValue = provinceValue;
    }

    /**
     * getCityValue
     *
     * @return CityValue
     */
    public String getCityValue() {
        return cityValue;
    }

    /**
     * setCityValue
     *
     * @param cityValue
     */
    public void setCityValue(String cityValue) {
        this.cityValue = cityValue;
    }

    /**
     * getCountyValue
     *
     * @return CountyValue
     */
    public String getCountyValue() {
        return countyValue;
    }

    /**
     * setCountyValue
     *
     * @param countyValue
     */
    public void setCountyValue(String countyValue) {
        this.countyValue = countyValue;
    }

    /**
     * 设置省的下标
     *
     * @param value
     */
    public void setOnePickerValue(int value) {
        if (value >= 0 && provinceEntityList.size() > value) {
            province.setValue(value);
        }
    }

    /**
     * 设置市的下标
     *
     * @param value
     */
    public void setTwoPickerValue(int value) {
        if (value >= 0 && cityEntityList.size() > value) {
            city.setValue(value);
        }
    }

    /**
     * 设置镇的下标
     *
     * @param value
     */
    public void setThreePickerValue(int value) {
        if (value >= 0 && countyEntityList.size() > value) {
            county.setValue(value);
        }
    }

    /**
     * onDraw
     *
     * @param component
     * @param canvas
     */
    @Override
    public void onDraw(Component component, Canvas canvas) {
        Paint paint = new Paint();
        int height = component.getHeight() / five;
        paint.setColor(Color.GRAY);
        paint.setAlpha((float) lyw);
        canvas.drawRect(zero, height * two, component.getWidth(), height * three, paint);
    }

    /**
     * 播放滚动音效
     */
    public void playSoundEffect() {
        if (mSoundHelper != null) {
            mSoundHelper.playSoundEffect();
        }
    }

    /**
     * 设置声音效果资源
     *
     * @param rawResId 声音效果资源 越小效果越好
     */
    public void setSoundEffectResource(String rawResId) {
        if (mSoundHelper == null) {
            mSoundHelper = new SoundHelper(getContext());
            mSoundHelper.load(getContext(), rawResId);
        }
    }

    /**
     * SoundPool 辅助类
     *
     * @author:wjt
     * @since 2021-04-06
     */
    private class SoundHelper {
        private Player mPlayer;
        private float mPlayVolume = twoty;

        /**
         * 构造
         *
         * @param context
         */
        @SuppressWarnings("deprecation")
        private SoundHelper(Context context) {
            try {
                RawFileDescriptor filDescriptor = getResourceManager()
                        .getRawFileEntry("resources/rawfile/qrcode.mp3").openRawFileDescriptor();
                Source source = new Source(filDescriptor.getFileDescriptor(),
                        filDescriptor.getStartPosition(), filDescriptor.getFileSize());
                mPlayer = new Player(context);
                mPlayer.setSource(source);
            } catch (IOException e) {
                LogUtils.log(LogUtils.DEBUG,"test",e.getMessage());
            }
        }

        /**
         * 初始化 SoundHelper
         *
         * @param context1
         * @return SoundHelper 对象
         */
        SoundHelper obtain(Context context1) {
            return new SoundHelper(context1);
        }

        /**
         * 加载音频资源
         *
         * @param context1 上下文
         * @param resId 音频资源
         */
        void load(Context context1, String resId) {
            if (mPlayer != null) {
                try {
                    RawFileDescriptor filDescriptor = getResourceManager()
                            .getRawFileEntry(resId).openRawFileDescriptor();
                    Source source = new Source(filDescriptor.getFileDescriptor(),
                            filDescriptor.getStartPosition(), filDescriptor.getFileSize());
                    mPlayer.setSource(source);
                } catch (IOException e) {
                    LogUtils.log(LogUtils.DEBUG,"test",e.getMessage());
                }
            }
        }

        /**
         * 设置音量
         *
         * @param playVolume 音频播放音量 range 0.0-1.0
         */
        void setPlayVolume(float playVolume) {
            this.mPlayVolume = playVolume;
        }

        /**
         * 获取音量
         *
         * @return 音频播放音量 range 0.0-1.0
         */
        float getPlayVolume() {
            return mPlayVolume;
        }

        /**
         * 播放声音效果
         */
        void playSoundEffect() {
            if (mPlayer != null) {
                mPlayer.prepare();
                mPlayer.setVolume(mPlayVolume);
                mPlayer.play();
            }
        }

        /**
         * 释放SoundPool
         */
        void release() {
            if (mPlayer != null) {
                mPlayer.release();
                mPlayer = null;
            }
        }
    }
}
